package es.sag.deck;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.Random;

import es.sag.deck.system.SysDefault;

public class Deck {
  private static final Random RND = new Random();
  
  private Card[] cards;
  
  public Deck() {
    cards = new SysDefault().cards;
  }
  
  public Deck(Order order) {
    cards = order.cards;
  }
  
  public void restartOrder() {
    Card sw = cards[0];
    for (int i=0; i<52; i++) {
      Card swc = cards[sw.getMnemonicPosition()-1];
      cards[sw.getMnemonicPosition()-1] = sw;
      sw = swc;
    }
  }
  
  public void shuffle() {
    Collections.shuffle(Arrays.asList(cards));
  }
  
  public int cut() {
    int pos = RND.nextInt(45) + 5;
    Card[] tmp = Arrays.copyOfRange(cards, 0, pos);
    for (int i=0, t=52-pos; i<t; i++) {
      cards[i] = cards[pos+i]; 
    }
    for (int i=0, t=tmp.length; i<t; i++) {
      cards[52-pos+i] = tmp[i];
    }
    return pos;
  }
  
  public int getPosition(Card card) {
    for (int i=0; i<52; i++) {
      if (cards[i].getValue() == card.getValue() && cards[i].getSuite() == card.getSuite()) {
        return i+1;
      }
    }
    return 0;
  }
  
  public Card getCard(int position) {
    int pos = position-1;
    if (pos == 52)
      pos = 0;
    else if (pos == -1)
      pos = 51;
    
    return cards[pos];
  }
  
  public Card getRandomCard() {
    int pos = RND.nextInt(52);
    return cards[pos];
  }
  
  public Iterator<Card> fwIterator() {
    return new Iterator<Card>() {
      private int idx = 0;
      
      @Override
      public boolean hasNext() {
        return (idx < 52);
      }

      @Override
      public Card next() {
        Card card = cards[idx];
        idx++;
        return card;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException();
      }
    };
  }
  
  public Iterator<Card> bwIterator() {
    return new Iterator<Card>() {
      private int idx = 51;
      
      @Override
      public boolean hasNext() {
        return (idx >= 0);
      }

      @Override
      public Card next() {
        Card card = cards[idx];
        idx--;
        return card;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException();
      }
    };
  }
}
